import networkx as nx
import tkinter as tk
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

adjacency_matrix = np.zeros((50, 50))

edges = [(1, 2), (1, 25), (1, 27), (2, 4), (3, 5), (3, 6), (3, 12), (3, 31), (5, 7), (5, 8), (5, 9), (5, 10), (6, 10),
         (6, 11), (10, 18), (10, 19), (11, 1), (11, 3), (12, 6), (12, 13), (12, 14), (12, 25), (12, 27), (12, 31), (13, 15),
         (13, 16), (16, 10), (16, 17), (17, 20), (17, 21), (22, 3), (22, 13), (22, 23), (22, 24), (22, 34), (22, 40), (24, 40),
         (25, 12), (25, 26), (27, 12), (27, 28), (28, 29), (28, 30), (31, 4), (31, 12), (31, 32), (31, 33), (32, 7), (36, 37),
         (36, 38), (36, 39), (36, 42), (39, 3), (39, 49), (40, 22), (40, 24), (40, 41), (40, 42), (42, 36), (42, 43), (44, 45),
         (44, 46), (44, 47), (47, 10), (47, 48), (49, 39), (49, 50)]

node_titles = {
    1: "从 ChatGPT 到 Sora：面向 AIGC 的四能教育和范式革新",
    2: "论教育实践的逻辑",
    3: "智慧教育:人工智能时代的教育变革",
    4: "教育理论与教育实践关系的逻辑考察",
    5: "信息时代智慧教育的内涵与特征",
    6: "智慧教育：教育信息化的新境界",
    7: "教学机智——教育智慧的意蕴",
    8: "智慧教育发展对策研究",
    9: "推进技术与教育的双向融合——教育信息化十年发展规划(2011-2020年)解读",
    10: "略论复杂系统与大成智慧",
    11: "从多元智能到多元智慧",
    12: "智慧教育环境中计算机辅助教学应用研究",
    13: "深度学习驱动的知识追踪研究进展综述",
    14: "智能导学系统中的知识追踪建模综述",
    15: "在线学习平台中知识追踪机制研究",
    16: "图神经网络综述",
    17: "机器学习图像分类程序的蜕变测试框架",
    18: "论系统工程",
    19: "现代科学技术和科学政策",
    20: "Eliminating human visual judgment from testing of financial charting software",
    21: "On testing non-testable programs",
    22: "5G时代生成式人工智能的风险与防范初探",
    23: "人脸信息泄露的风险评估及其治理",
    24: "AI热潮下 深度伪造 问题不容忽视",
    25: "智能平台兴起与智能体涌现:大模型将变革社会与文明",
    26: "深度强化学习实战：用 OpenAI Gym 构建智能体",
    27: "基于大模型增强的通用人工智能教师架构",
    28: "大模型关键技术与未来发展方向——从 ChatGPT 谈起",
    29: "Evaluating large language models trained on code",
    30: "Visualchatgpt: talking, drawing and editing with visual foundation models",
    31: "构筑 人工智能 + 教育 的生态系统",
    32: "智能时代：智慧的教育是什么？",
    33: "互联网+'的六大特征",
    34: "人工智能综述: AI的发展",
    35: "人工智能的历史与发展",
    36: "人工智能的发展综述",
    37: "脑模拟与神经计算机",
    38: "人工智能导论",
    39: "人工智能的历史和前景",
    40: "人工智能技术的伦理问题及其对策研究",
    41: "现代科技伦理学概论",
    42: "人工智能原理与应用",
    43: "专家系统与人工神经网络的发展与结合",
    44: "人工智能技术冲击和中国职业变迁方向",
    45: "人工智能技术、任务属性与职业可替代风险：来自微观层面的经验证据",
    46: "Distorted Innovation：Does the Market Get the Direction of Technology Right",
    47: "工业机器人与劳动力的空间配置",
    48: "机器人的兴起如何影响中国劳动力市场?——来自制造业上市公司的证据",
    49: "人类为什么不会被人工智能取代?",
    50: "人工智能无法全面取代人类",
}


def create_adjacency_matrix(num_nodes, edge_list):
    """
    根据给定的边生成一个邻接矩阵。

    参数:
    num_nodes: 节点的数量
    edge_list: 包含所有边的列表，每个边是一个二元组 (start_node, end_node)

    返回:
    一个numpy数组，表示生成的邻接矩阵。
    """
    adjacency_matrix = np.zeros((num_nodes, num_nodes))
    for edge in edge_list:
        start, end = edge
        adjacency_matrix[start - 1][end - 1] = 1  # 将1放在对应节点之间的连接处
    return adjacency_matrix


# 用于显示邻接矩阵的函数
def display_adjacency_matrix():
    # 获取邻接矩阵
    matrix = create_adjacency_matrix(50, edges)

    # 创建新的Tkinter窗口
    matrix_window = tk.Toplevel()
    matrix_window.title('邻接矩阵')

    # 创建一个文本框用来显示矩阵
    text = tk.Text(matrix_window, height=50, width=100)
    text.pack(side=tk.LEFT, fill=tk.Y)
    scrollbar = tk.Scrollbar(matrix_window)
    scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

    # 将文本框与滚动条关联
    text.config(yscrollcommand=scrollbar.set)
    scrollbar.config(command=text.yview)

    # 将矩阵内容添加到文本框中展示
    for row in matrix:
        row_str = ' '.join(str(int(val)) for val in row) + '\n'
        text.insert(tk.END, row_str)

    # 禁止编辑文本框内容
    text.config(state=tk.DISABLED)

# 在原有基础上添加显示邻接矩阵的函数调用
display_adjacency_matrix()

# 创建一个有向图
G = nx.DiGraph()

# 添加结点和边
for node in range(1, 51):
    G.add_node(node, title=node_titles.get(node, str(node)))
G.add_edges_from(edges)

# 计算PageRank值
pr = nx.pagerank(G)

# 根据PageRank值对结点进行排序
sorted_nodes = sorted(pr.items(), key=lambda x: x[1], reverse=True)

# 创建主Tkinter窗口
root = tk.Tk()
root.title("结点网络图及重要度")

# 创建显示区域
fig, ax = plt.subplots(figsize=(8, 6))

# 调整结点位置，更重要的节点（即PageRank值较高的节点）位于中心

# 使用spring_layout算法优化节点布局，尽量避免节点重叠，并根据PageRank值调整节点大小
pos = nx.spring_layout(G, k=0.5, iterations=20)
# 绘制图形
# 基于PageRank值动态计算节点大小
node_sizes = [pr[node] * 50000 for node in G.nodes()]
node_colors = [pr[node] for node in G]  # PageRank值越高，颜色越深
# 绘制图形
nx.draw(G, pos, with_labels=True, node_size=node_sizes, ax=ax, cmap=plt.cm.RdYlBu, node_color=list(pr.values()))

def on_move(event):
    closest_node = None
    min_dist = float('inf')
    for node, p in pos.items():
        dist = np.sqrt((p[0] - event.xdata)**2 + (p[1] - event.ydata)**2)
        if dist < min_dist:
            min_dist = dist
            closest_node = node
    if closest_node and min_dist < 0.1:  # 根据实际情况调整距离阈值
        article_label.config(text=node_titles.get(closest_node, "No title"))
    else:
        article_label.config(text="")


# 创建用于显示文章名称的标签，并将其放置在顶部
article_label = tk.Label(root, text="")
article_label.pack(side=tk.TOP, fill=tk.X)


# 将图表嵌入Tkinter窗口，放置在标签下方
canvas = FigureCanvasTkAgg(fig, master=root)
canvas_widget = canvas.get_tk_widget()
canvas_widget.pack(side=tk.TOP, fill=tk.BOTH, expand=True)

# 绑定鼠标移动事件
canvas.mpl_connect('motion_notify_event', on_move)

# 新增代码——计算每个节点的入度和出度
in_degree = G.in_degree()
out_degree = G.out_degree()

# 创建一个新窗口来显示每个结点的重要度和入度出度
importance_root = tk.Toplevel()
importance_root.title("结点信息")

# 创建显示重要度和入度出度的列表框
listbox = tk.Listbox(importance_root, width=150, height=20)
listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

# 添加滚动条
scrollbar = tk.Scrollbar(importance_root)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
listbox.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=listbox.yview)

# 往列表框中添加数据，包括入度和出度
for node, importance in sorted_nodes:
    node_in_degree = in_degree[node]
    node_out_degree = out_degree[node]
    listbox.insert(tk.END, '结点 {}: 重要度 {:.4f}, 入度 {}, 出度 {}'.format(node, importance, node_in_degree, node_out_degree))
print(f"1 小时速推git+gitee ")
# 启动Tkinter事件循环
root.mainloop()
